// mysignal.cc
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;

void printPending(const sigset_t &pending)
{
    // 不能自己进行位操作，只能调用接口
    for (int signo = 31; signo >= 1; --signo)
    {
        if (sigismember(&pending, signo))  // 判断制定信号是否在目标集合中
            cout << "1";
        else
            cout << "0";
    }
    cout << endl;
}

int main()
{
    sigset_t bset, oset;
    sigemptyset(&bset);
    sigemptyset(&oset);
    for (int i = 1; i < 32; ++i)
    {
        sigaddset(&bset, i);
    }
    sigprocmask(SIG_SETMASK, &bset, &oset);

    sigset_t pending;
    while (true)
    {
        // 2.1 获取内核中的pending位图，即未决信号集
        int n = sigpending(&pending);
        if (n < 0)
            continue;
        
        // 2.2 打印
        printPending(pending);
        sleep(1);
    }

    return 0;
}

// void handler(int signo)
// {
//     cout << "catch a signo: " << signo << endl;
// }

// int main()
// {
//     // 0. 对2号信号进行自定义捕捉
//     signal(2, handler);

//     // 1.1 先对2号信号进行屏蔽 -- 数据预备
//     // 定义信号集对象，并清空初始化
//     sigset_t bset, oset; // 局部变量，在用户栈上开辟的空间，属于用户区
//     sigemptyset(&bset);
//     sigemptyset(&oset);
//     sigaddset(&bset, 2); // 只是设置了bset的2号信号屏蔽，并没有设置进进程的task_struct里

//     // 1.2 调用系统调用，将bset数据设置进内核
//     sigprocmask(SIG_SETMASK, &bset, &oset); // 设置阻塞信号集，在进程PCB里阻塞2号信号

//     // 2. 重复打印当前进程的pending
//     sigset_t pending;
//     int cnt = 0;
//     while (true)
//     {
//         // 2.1 获取内核中的pending位图，即未决信号集
//         int n = sigpending(&pending);
//         if (n < 0)
//             continue;
        
//         // 2.2 打印
//         printPending(pending);
        
//         // 2.3 解除阻塞
//         if (cnt == 10)
//         {
//             cout << "unblock 2 signo" << endl;
//             sigprocmask(SIG_SETMASK, &oset, nullptr);
//         }

//         ++cnt;
//         sleep(1);
//     }
// }

// int main()
// {
//     // signal(2, SIG_IGN);
//     signal(2, SIG_DFL);

//     while (1)
//     {
//         cout << "hello signal" << endl;
//         sleep(1);
//     }
// }